package main

import (
	"fmt"
	"io"
	"os"
)
import "os/exec"

func main() {
	// demo-1
	// exec.Command 函数帮助我们创建一个表示这个外部进程的对象
	dateCmd := exec.Command("date") // date 没有参数或者输入，仅打印一些信息到标准输出流

	// Cmd.Output 该函数等待命令运行完成，并收集命令的输出
	dateOut, err := dateCmd.Output() // 如果没有出错，dateOut 将获取到日期信息的字节
	if err != nil {
		panic(err)
	}
	fmt.Println("> date")
	fmt.Println(string(dateOut)) // Tue Nov 28 14:17:29 CST 2023

	// demo-2
	// 从外部进程的 stdin 输入数据，并从 stdout 读取输出结果
	grepCmd := exec.Command("grep", "hello")
	// 2.1.获取输入/输出管道
	grepIn, _ := grepCmd.StdinPipe()
	grepOut, _ := grepCmd.StdoutPipe()
	grepErr, _ := grepCmd.StderrPipe()

	// 2.2. 运行这个进程（忽略了错误检测）
	_ = grepCmd.Start()
	// 2.3. 写入 stdin（忽略了错误检测）
	_, _ = grepIn.Write([]byte("hello grep\ngoodbye grep"))
	_ = grepIn.Close()
	// 2.4. 读取 stdout、stderr（忽略了错误检测）
	grepBytes, _ := io.ReadAll(grepOut)
	grepErrBytes, _ := io.ReadAll(grepErr)
	// 2.5. 最后等待程序运行结束（忽略了错误检测）
	_ = grepCmd.Wait()

	fmt.Println("> grep hello")
	fmt.Println(string(grepBytes)) // hello grep
	_, _ = fmt.Fprintln(os.Stderr, "occur error:", string(grepErrBytes))

	// 可以使用 bash命令的 -c 选项：执行我们想要执行的命令
	lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
	lsOut, err := lsCmd.Output()
	if err != nil {
		panic(err)
	}
	fmt.Println("> ls -a -l -h")
	fmt.Println(string(lsOut))
}
